package vn.vfriends.mcms.site.service.impl;

import java.io.IOException;
import java.io.OutputStream;
import javax.annotation.ManagedBean;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.servlet.ServletContext;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import vn.vfriends.mcms.site.service.FTPFileService;

/**
 *
 * @author tuan@vfriends.vn
 */
@ManagedBean
public class FTPFileServiceImpl implements FTPFileService {

    private static final Logger logger = LoggerFactory.getLogger(FTPFileServiceImpl.class);
    
    private static String server;
    private static String username;
    private static String password;
    
    private static String base_path;
    
    @Resource private WebServiceContext wsContext;
    
    public FTPFileServiceImpl() {
        ServletContext servletContext;
        FacesContext facesContext = FacesContext.getCurrentInstance();
        if(facesContext != null) {
            servletContext = (ServletContext) facesContext.getExternalContext().getContext();
        } else if(wsContext != null) {
            servletContext = (ServletContext)wsContext.getMessageContext().get(MessageContext.SERVLET_CONTEXT);
        } else {
            return;
        }
        server = servletContext.getInitParameter("FTP_SERVER");
        username = servletContext.getInitParameter("FTP_USER");
        password = servletContext.getInitParameter("FTP_PASSWORD");
        base_path = servletContext.getInitParameter("FTP_PATH");
    }
    
    @Override
    public FTPFile[] listFiles(String path) throws Exception {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient.setAutodetectUTF8(true);
            ftpClient.connect(server);
            if(logger.isDebugEnabled()) {
                showServerReply(ftpClient);
            }
            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                logger.info("Connect failed");
                throw new Exception("Connect failed");
            }
            boolean success = ftpClient.login(username, password);
            if(logger.isDebugEnabled()) {
                showServerReply(ftpClient);
            }
            if (!success) {
                logger.info("Could not login to the server");
                throw new Exception("Could not login to the server");
            }
            return ftpClient.listFiles(base_path + path);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw e;
        } finally {
            try {
                if (ftpClient.isConnected()) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                }
            } catch (IOException ex) {
                logger.error(ex.getMessage(), ex);
                throw ex;
            }
        }
    }

    private void showServerReply(FTPClient ftpClient) {
        String[] replies = ftpClient.getReplyStrings();
        if (replies != null && replies.length > 0) {
            for (String aReply : replies) {
                logger.info("SERVER: " + aReply);
            }
        }
    }
    
    @Override
    public boolean retrieveFile(String remote, OutputStream local) throws Exception {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient.setAutodetectUTF8(true);
            ftpClient.connect(server);
            if(logger.isDebugEnabled()) {
                showServerReply(ftpClient);
            }
            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                logger.info("Connect failed");
                throw new Exception("Connect failed");
            }
            boolean success = ftpClient.login(username, password);
            if(logger.isDebugEnabled()) {
                showServerReply(ftpClient);
            }
            if (!success) {
                logger.info("Could not login to the server");
                throw new Exception("Could not login to the server");
            }
            return ftpClient.retrieveFile(base_path + remote, local);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw e;
        } finally {
            try {
                if (ftpClient.isConnected()) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                }
            } catch (IOException ex) {
                logger.error(ex.getMessage(), ex);
                throw ex;
            }
        }
    }
}
